home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i092: An Automounter for NFS systems, Part04/13
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: ac520e2c 91ff7e99 185b47fc 54e5ad2f
-
- Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
- Posting-number: Volume 21, Issue 92
- Archive-name: amd/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 13)."
- # Contents: amq.x amq_xdr.c clock.c doc/amd.bib doc/nh.doc info_file.c
- # mount_fs.c nfs_prot_svc.c restart.c sched.c
- # Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:02 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'amq.x' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'amq.x'\"
- else
- echo shar: Extracting \"'amq.x'\" \(4120 characters\)
- sed "s/^X//" >'amq.x' <<'END_OF_FILE'
- X/*
- X * $Id: amq.x,v 5.1.1.1 90/01/11 17:02:14 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * Protocol description used by the amq program
- X */
- X
- Xconst AMQ_STRLEN = 1024; /* Maximum length of a pathname */
- X
- X/*
- X * The type dirpath is the pathname of a directory
- X */
- Xtypedef string amq_string<AMQ_STRLEN>;
- X
- X/*
- X * The type time_type should correspond to the system time_t
- X */
- Xtypedef long time_type;
- X
- X/*
- X * A tree of what is mounted
- X */
- Xstruct amq_mount_tree {
- X amq_string mt_mountinfo; /* Mounted filesystem */
- X amq_string mt_directory; /* Virtual mount */
- X amq_string mt_mountpoint; /* Mount point */
- X amq_string mt_type; /* Filesystem type */
- X time_type mt_mounttime; /* Mount time */
- X u_short mt_mountuid; /* Mounter */
- X int mt_getattr; /* Count of getattrs */
- X int mt_lookup; /* Count of lookups */
- X int mt_readdir; /* Count of readdirs */
- X int mt_readlink; /* Count of readlinks */
- X int mt_statfs; /* Count of statfss */
- X amq_mount_tree *mt_next; /* Sibling mount tree */
- X amq_mount_tree *mt_child; /* Child mount tree */
- X};
- Xtypedef amq_mount_tree *amq_mount_tree_p;
- X
- X/*
- X * List of mounted filesystems
- X */
- Xstruct amq_mount_info {
- X amq_string mi_type; /* Type of mount */
- X amq_string mi_mountpt; /* Mount point */
- X amq_string mi_mountinfo; /* Mount info */
- X amq_string mi_fserver; /* Fileserver */
- X int mi_error; /* Error code */
- X int mi_refc; /* References */
- X int mi_up; /* Filesystem available */
- X};
- Xtypedef amq_mount_info amq_mount_info_list<>;
- X
- X/*
- X * A list of mount trees
- X */
- Xtypedef amq_mount_tree_p amq_mount_tree_list<>;
- X
- X/*
- X * System wide stats
- X */
- Xstruct amq_mount_stats {
- X int as_drops; /* Dropped requests */
- X int as_stale; /* Stale NFS handles */
- X int as_mok; /* Succesful mounts */
- X int as_merr; /* Failed mounts */
- X int as_uerr; /* Failed unmounts */
- X};
- X
- Xenum amq_opt {
- X AMOPT_DEBUG=0,
- X AMOPT_LOGFILE=1,
- X AMOPT_XLOG=2,
- X AMOPT_FLUSHMAPC=3
- X};
- X
- Xstruct amq_setopt {
- X amq_opt as_opt; /* Option */
- X amq_string as_str; /* String */
- X};
- X
- Xprogram AMQ_PROGRAM {
- X version AMQ_VERSION {
- X /*
- X * Does no work. It is made available in all RPC services
- X * to allow server reponse testing and timing
- X */
- X void
- X AMQPROC_NULL(void) = 0;
- X
- X /*
- X * Returned the mount tree descending from
- X * the given directory. The directory must
- X * be a top-level mount point of the automounter.
- X */
- X amq_mount_tree_p
- X AMQPROC_MNTTREE(amq_string) = 1;
- X
- X /*
- X * Force a timeout unmount on the specified directory.
- X */
- X void
- X AMQPROC_UMNT(amq_string) = 2;
- X
- X /*
- X * Obtain system wide statistics from the automounter
- X */
- X amq_mount_stats
- X AMQPROC_STATS(void) = 3;
- X
- X /*
- X * Obtain full tree
- X */
- X amq_mount_tree_list
- X AMQPROC_EXPORT(void) = 4;
- X
- X /*
- X * Control debug options.
- X * Return status:
- X * -1: debug not available
- X * 0: everything wonderful
- X * >0: number of options not recognised
- X */
- X int
- X AMQPROC_SETOPT(amq_setopt) = 5;
- X
- X /*
- X * List of mounted filesystems
- X */
- X amq_mount_info_list
- X AMQPROC_GETMNTFS(void) = 6;
- X } = 1;
- X} = 300019; /* Allocated by Sun, 89/8/29 */
- END_OF_FILE
- if test 4120 -ne `wc -c <'amq.x'`; then
- echo shar: \"'amq.x'\" unpacked with wrong size!
- fi
- # end of 'amq.x'
- fi
- if test -f 'amq_xdr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'amq_xdr.c'\"
- else
- echo shar: Extracting \"'amq_xdr.c'\" \(4678 characters\)
- sed "s/^X//" >'amq_xdr.c' <<'END_OF_FILE'
- X/*
- X * $Id: amq_xdr.c,v 5.1.1.1 90/01/11 17:04:23 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X#include "amq.h"
- X
- X
- Xbool_t
- Xxdr_amq_string(xdrs, objp)
- X XDR *xdrs;
- X amq_string *objp;
- X{
- X if (!xdr_string(xdrs, objp, AMQ_STRLEN)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_time_type(xdrs, objp)
- X XDR *xdrs;
- X time_type *objp;
- X{
- X if (!xdr_long(xdrs, objp)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_tree(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_tree *objp;
- X{
- X if (!xdr_amq_string(xdrs, &objp->mt_mountinfo)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mt_directory)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mt_mountpoint)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mt_type)) {
- X return (FALSE);
- X }
- X if (!xdr_time_type(xdrs, &objp->mt_mounttime)) {
- X return (FALSE);
- X }
- X if (!xdr_u_short(xdrs, &objp->mt_mountuid)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mt_getattr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mt_lookup)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mt_readdir)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mt_readlink)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mt_statfs)) {
- X return (FALSE);
- X }
- X if (!xdr_pointer(xdrs, (char **)&objp->mt_next, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
- X return (FALSE);
- X }
- X if (!xdr_pointer(xdrs, (char **)&objp->mt_child, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_tree_p(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_tree_p *objp;
- X{
- X if (!xdr_pointer(xdrs, (char **)objp, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_info(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_info *objp;
- X{
- X if (!xdr_amq_string(xdrs, &objp->mi_type)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mi_mountpt)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mi_mountinfo)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->mi_fserver)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mi_error)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mi_refc)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->mi_up)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_info_list(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_info_list *objp;
- X{
- X if (!xdr_array(xdrs, (char **)&objp->amq_mount_info_list_val, (u_int *)&objp->amq_mount_info_list_len, ~0, sizeof(amq_mount_info), xdr_amq_mount_info)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_tree_list(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_tree_list *objp;
- X{
- X if (!xdr_array(xdrs, (char **)&objp->amq_mount_tree_list_val, (u_int *)&objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), xdr_amq_mount_tree_p)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_amq_mount_stats(xdrs, objp)
- X XDR *xdrs;
- X amq_mount_stats *objp;
- X{
- X if (!xdr_int(xdrs, &objp->as_drops)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->as_stale)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->as_mok)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->as_merr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->as_uerr)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_amq_opt(xdrs, objp)
- X XDR *xdrs;
- X amq_opt *objp;
- X{
- X if (!xdr_enum(xdrs, (enum_t *)objp)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_amq_setopt(xdrs, objp)
- X XDR *xdrs;
- X amq_setopt *objp;
- X{
- X if (!xdr_amq_opt(xdrs, &objp->as_opt)) {
- X return (FALSE);
- X }
- X if (!xdr_amq_string(xdrs, &objp->as_str)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- END_OF_FILE
- if test 4678 -ne `wc -c <'amq_xdr.c'`; then
- echo shar: \"'amq_xdr.c'\" unpacked with wrong size!
- fi
- # end of 'amq_xdr.c'
- fi
- if test -f 'clock.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'clock.c'\"
- else
- echo shar: Extracting \"'clock.c'\" \(4452 characters\)
- sed "s/^X//" >'clock.c' <<'END_OF_FILE'
- X/*
- X * $Id: clock.c,v 5.1 89/11/17 18:19:50 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1989 Jan-Simon Pendry
- X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1989 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * Callouts.
- X *
- X * Modelled on kernel object of the same name.
- X * See usual references.
- X *
- X * Use of a heap-based mechanism was rejected:
- X * 1. more complext implementation needed.
- X * 2. not obvious that a list is too slow for amd.
- X */
- X
- X#include "am.h"
- X
- Xtypedef struct callout callout;
- Xstruct callout {
- X callout *c_next; /* List of callouts */
- X void (*c_fn)(); /* Function to call */
- X voidp c_closure; /* Closure to pass to call */
- X time_t c_time; /* Time of call */
- X int c_id; /* Unique identifier */
- X};
- X
- Xstatic callout callouts; /* List of pending callouts */
- Xstatic callout *free_callouts; /* Cache of free callouts */
- Xstatic int nfree_callouts; /* Number on free list */
- Xstatic int callout_id; /* Next free callout identifier */
- Xtime_t next_softclock; /* Time of next call to softclock() */
- X
- X/*
- X * Number of callout slots we keep on the free list
- X */
- X#define CALLOUT_FREE_SLOP 10
- X
- X/*
- X * Assumption: valid id's are non-zero.
- X */
- X#define CID_ALLOC() (++callout_id)
- X#define CID_UNDEF (0)
- X
- Xstatic callout *alloc_callout()
- X{
- X callout *cp = free_callouts;
- X if (cp) {
- X --nfree_callouts;
- X free_callouts = free_callouts->c_next;
- X return cp;
- X }
- X return ALLOC(callout);
- X}
- X
- Xstatic void free_callout(cp)
- Xcallout *cp;
- X{
- X if (nfree_callouts > CALLOUT_FREE_SLOP) {
- X free((voidp) cp);
- X } else {
- X cp->c_next = free_callouts;
- X free_callouts = cp;
- X nfree_callouts++;
- X }
- X}
- X
- X/*
- X * Schedule a callout.
- X *
- X * (*fn)(closure) will be called at clocktime() + secs
- X */
- Xint timeout(secs, fn, closure)
- Xunsigned int secs;
- Xvoid (*fn)();
- Xvoidp closure;
- X{
- X callout *cp, *cp2;
- X time_t t = clocktime() + secs;
- X
- X /*
- X * Allocate and fill in a new callout structure
- X */
- X callout *cpnew = alloc_callout();
- X cpnew->c_closure = closure;
- X cpnew->c_fn = fn;
- X cpnew->c_time = t;
- X cpnew->c_id = CID_ALLOC();
- X
- X if (t < next_softclock)
- X next_softclock = t;
- X
- X /*
- X * Find the correct place in the list
- X */
- X for (cp = &callouts; cp2 = cp->c_next; cp = cp2)
- X if (cp2->c_time >= t)
- X break;
- X
- X /*
- X * And link it in
- X */
- X cp->c_next = cpnew;
- X cpnew->c_next = cp2;
- X
- X /*
- X * Return callout identifier
- X */
- X return cpnew->c_id;
- X}
- X
- X/*
- X * De-schedule a callout
- X */
- Xvoid untimeout(id)
- Xint id;
- X{
- X callout *cp, *cp2;
- X for (cp = &callouts; cp2 = cp->c_next; cp = cp2) {
- X if (cp2->c_id == id) {
- X cp->c_next = cp2->c_next;
- X free_callout(cp2);
- X break;
- X }
- X }
- X}
- X
- X/*
- X * Clock handler
- X */
- Xint softclock()
- X{
- X time_t now;
- X callout *cp;
- X
- X do {
- X if (task_notify_todo)
- X task_notify();
- X
- X now = clocktime();
- X
- X /*
- X * While there are more callouts waiting...
- X */
- X while ((cp = callouts.c_next) && cp->c_time <= now) {
- X /*
- X * Extract first from list, save fn & closure and
- X * unlink callout from list and free.
- X * Finally call function.
- X *
- X * The free is done first because
- X * it is quite common that the
- X * function will call timeout()
- X * and try to allocate a callout
- X */
- X void (*fn)() = cp->c_fn;
- X voidp closure = cp->c_closure;
- X
- X callouts.c_next = cp->c_next;
- X free_callout(cp);
- X#ifdef DEBUG
- X /*dlog("Calling %#x(%#x)", fn, closure);*/
- X#endif
- X (*fn)(closure);
- X }
- X
- X } while (task_notify_todo);
- X
- X /*
- X * Return number of seconds to next event,
- X * or 0 if there is no event.
- X */
- X if (cp = callouts.c_next)
- X return cp->c_time - now;
- X return 0;
- X}
- END_OF_FILE
- if test 4452 -ne `wc -c <'clock.c'`; then
- echo shar: \"'clock.c'\" unpacked with wrong size!
- fi
- # end of 'clock.c'
- fi
- if test -f 'doc/amd.bib' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/amd.bib'\"
- else
- echo shar: Extracting \"'doc/amd.bib'\" \(3898 characters\)
- sed "s/^X//" >'doc/amd.bib' <<'END_OF_FILE'
- X% $Id: amd.bib,v 5.1 89/11/17 18:24:37 jsp Exp Locker: jsp $
- X%
- X% Copyright (c) 1989 Jan-Simon Pendry
- X% Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- X% Copyright (c) 1989 The Regents of the University of California.
- X% All rights reserved.
- X%
- X% This code is derived from software contributed to Berkeley by
- X% Jan-Simon Pendry at Imperial College, London.
- X%
- X% Redistribution and use in source and binary forms are permitted
- X% provided that the above copyright notice and this paragraph are
- X% duplicated in all such forms and that any documentation,
- X% advertising materials, and other materials related to such
- X% distribution and use acknowledge that the software was developed
- X% by Imperial College of Science, Technology and Medicine, London, UK.
- X% The names of the College and University may not be used to endorse
- X% or promote products derived from this software without specific
- X% prior written permission.
- X% THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X% IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X%
- X% %W% (Berkeley) %G%
- X
- X@inproceedings{usenix:automounter
- X ,author = "Brent Callaghan and Tom Lyon"
- X ,month = "January"
- X ,year = "1989"
- X ,title = "{The Automounter}"
- X ,booktitle = "Usenix Conference Proceedings, {\rm San Diego, California}"
- X ,organization = "Usenix Association"
- X ,pages = "43-51"
- X}
- X
- X@inproceedings{mit:hesiod
- X ,author = "Stephen P. Dyer"
- X ,title = "{The {\em Hesiod} Name Server}"
- X ,booktitle = "Usenix Conference Proceedings, {\rm Dallas, Texas}"
- X ,year = "1988"
- X ,month = "February"
- X ,organization = "Usenix Association"
- X ,pages = "183--189"
- X}
- X
- X@techreport{mit:rvd
- X ,author = "M. Greenwald and J. V. Sciver"
- X ,title = "{Remote Virtual Disk Protocol Specification}"
- X ,year = "1986"
- X ,institution = "Massachusetts Institute of Technology"
- X ,address = "Cambridge, Massachusetts"
- X}
- X
- X@inbook{bsd:ufs
- X ,author = "Samuel J. Leffler and others"
- X ,year = "1989"
- X ,title = "The Design and Implementation of the 4.3BSD UNIX Operating System"
- X ,chapter = "7"
- X ,pages = "187--223"
- X ,publisher = "Addison-Wesley"
- X}
- X
- X@techreport{rfc:icmp
- X ,author = "J. Postel"
- X ,title = "{Internet Control Message Protocol}"
- X ,year = "1981"
- X ,month = "September"
- X ,institution = "SRI Network Information Center"
- X ,address = "Menlo Park, California"
- X ,type = "RFC"
- X ,number = "792"
- X}
- X
- X@techreport{rfc:ip
- X ,author = "J. Postel"
- X ,title = "{Internet Protocol}"
- X ,year = "1981"
- X ,month = "September"
- X ,institution = "SRI Network Information Center"
- X ,address = "Menlo Park, California"
- X ,type = "RFC"
- X ,number = "791"
- X}
- X
- X@incollection{sun:yp
- X ,author = "{Sun Microsystems}"
- X ,year = "1988"
- X ,booktitle = "System \& Network Administration"
- X ,title = "{The Sun YP Service}"
- X ,month = "May"
- X ,chapter = "14"
- X ,pages = "349--371"
- X ,edition = "First"
- X ,publisher = "Sun Microsystems, Inc"
- X ,address = "Mountain View, California"
- X}
- X
- X@incollection{sun:automount
- X ,author = "{Sun Microsystems}"
- X ,year = "1988"
- X ,booktitle = "SunOS Reference Manual"
- X ,title = "Automount"
- X ,month = "May"
- X ,chapter = "8"
- X ,pages = "1583--1585"
- X ,edition = "First"
- X ,publisher = "Sun Microsystems, Inc"
- X ,address = "Mountain View, California"
- X}
- X
- X@incollection{sun:rpc
- X ,author = "{Sun Microsystems}"
- X ,year = "1988"
- X ,booktitle = "Network Programming"
- X ,title = "{Remote Procedure Calls: Protocol Specification}"
- X ,month = "May"
- X ,chapter = "6"
- X ,pages = "143--163"
- X ,edition = "First"
- X ,publisher = "Sun Microsystems, Inc"
- X ,address = "Mountain View, California"
- X}
- X
- X@incollection{sun:nfs
- X ,author = "{Sun Microsystems}"
- X ,year = "1988"
- X ,booktitle = "Network Programming"
- X ,title = "{Network File System: Version 2 Protocol Specification}"
- X ,month = "May"
- X ,chapter = "7"
- X ,pages = "165--185"
- X ,edition = "First"
- X ,publisher = "Sun Microsystems, Inc"
- X ,address = "Mountain View, California"
- X}
- END_OF_FILE
- if test 3898 -ne `wc -c <'doc/amd.bib'`; then
- echo shar: \"'doc/amd.bib'\" unpacked with wrong size!
- fi
- # end of 'doc/amd.bib'
- fi
- if test -f 'doc/nh.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/nh.doc'\"
- else
- echo shar: Extracting \"'doc/nh.doc'\" \(4900 characters\)
- sed "s/^X//" >'doc/nh.doc' <<'END_OF_FILE'
- X% Change page size parameters for A4 paper on LaserWriter,
- X% allowing for headers and footers. Define some new macros for headers
- X% and footers too.
- X%
- X% MJW 7 Jan 1987
- X%
- X% USAGE
- X%
- X% To enable this use \pagestyle{footers}.
- X% This also overrides automatically getting chapter titles in headers, but you
- X% could restore this by using \leftmark and \rightmark
- X% in your own headers and footers. These macros are set by \chaptermark (and
- X% possibly other things too). In one-sided printing all pages are right ones.
- X%
- X% One-Sided Printing
- X%
- X% \setheader{your header}
- X% \setfooter{your footer}
- X% \setchapterhead{header on first page of a chapter}
- X% \setchapterfoot{footer on first page of a chapter}
- X%
- X% Two-sided Printing
- X%
- X% \setbothheaders{the left one (even no. pages}{the right one (odd)}
- X% \setbothfooters{the left one}{the right one}
- X% \setchapterhead{header on first page of a chapter}
- X% \setchapterfoot{footer on first page of a chapter}
- X%
- X% Examples
- X%
- X% To get a page number use \thepage. Use \hfil to get centring etc.
- X% Example \setheader{A\hfil\thepage\hfil B}
- X% produces A at the extreme left of the page, the number in the middle
- X% and B at the extreme right.
- X%
- X% The following produces chapter title at top left, page number top right,
- X% with a line across the page underneath them,
- X% Project 1022(1041) bottom left, Task 19.1 bottom right.
- X% Except on the first page of a chapter when the heading is empty, and
- X% the footer is as before, but with the page number in the middle.
- X% \pagestyle{footers}
- X% \setheader{\vbox{\hbox to\hsize{\rightmark\hfil\thepage}\vskip 2pt\hrule}}
- X% \setfooter{Project 1022(1041)\hfil Task 19.1}
- X% \setchapterfoot{Project 1022(1041)\hfil\thepage \hfil Task 19.1}
- X
- X\oddsidemargin 16pt % MJW actually get 1/2 inch (=32pt) margin because
- X % of printer offset. was 1pt
- X\evensidemargin 16pt % was 1pt
- X\marginparwidth 30pt % these gain 53pt width
- X\topmargin 5pt % gains 26pt height (MJW was 16pt)
- X\headheight 14pt % gains 11pt height (MJW was 1pt)
- X\headsep 25pt % gains 24pt height (MJW was 1pt)
- X%\footheight 12 pt % cannot be changed as number must fit
- X\footskip 24pt % gains 6pt height
- X\textheight % 528 + 26 + 11 + 24 + 6 + 55 for luck -16 +32 (heads: -10 -15)
- X% 650pt
- X% 666pt
- X 641pt
- X\textwidth % 360 + 53 + 47 for luck -15 +8
- X 453pt
- X%\pagestyle{myheadings}
- X%\markboth{LEFT}{RIGHT}
- X%left = even, right = odd for two-sided
- X% everything is right for one-sided
- X\def\evenheadline{}\def\oddheadline{}
- X\def\evenfootline{}\def\oddfootline{}
- X
- X% Use these to set headers and footers for two-sided printing.
- X\def\setbothheaders#1#2{\def\evenheadline{#1}\def\oddheadline{#2}}
- X\def\setbothfooters#1#2{\def\evenfootline{#1}\def\oddfootline{#2}}
- X
- X% Use these for one-sided printing.
- X\def\setheader#1{\def\oddheadline{#1}}\def\setfooter#1{\def\oddfootline{#1}}
- X
- X% To set footer on first page of a chapter
- X\def\setchapterfoot#1{\def\chapterfoot{#1}}
- X\def\setchapterhead#1{\def\chapterhead{#1}}
- X
- X% Initialise footers to the page number.
- X\setbothfooters{\hfil\thepage\hfil}{\hfil\thepage\hfil}
- X
- X% Initialise chapter footer to page number, header empty.
- X\setchapterfoot{\hfil\thepage \hfil}
- X\setchapterhead{}
- X
- X% My version of \chapter
- X\def\chapter{\clearpage % Starts new page.
- X% \if@twoside \cleardoublepage
- X% \else\clearpage\fi % Starts new page.
- X \thispagestyle{chapterpage} % Page style of chapter page is 'chapterpage'
- X \global\@topnum\z@ % Prevents figures from going at top of page.
- X \@afterindentfalse % Suppresses indent in first paragraph. Change
- X \secdef\@chapter\@schapter} % to \@afterindenttrue to have indent.
- X
- X% Style for first page of a chapter
- X\def\ps@chapterpage{\let\@mkboth\markboth
- X\def\@evenhead{\chapterhead}\def\@oddhead{\chapterhead}
- X\def\@evenfoot{\chapterfoot}\def\@oddfoot{\chapterfoot}}
- X
- X% Style for headers AND footers.
- X\if@twoside % If two-sided printing.
- X\def\ps@footers{\let\@mkboth\markboth
- X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
- X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
- X% Chapter stuff
- X\def\chaptermark##1{\markboth{\uppercase{\ifnum \c@secnumdepth >\m@ne
- X \@chapapp\ \thechapter. \ \fi ##1}}{}}
- X\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@
- X \thesection. \ \fi ##1}}}
- X}
- X\else % If one-sided printing.
- X\def\ps@footers{\let\@mkboth\markboth
- X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
- X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
- X% Chapter stuff
- X\def\chaptermark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\m@ne
- X \@chapapp\ \thechapter. \ \fi ##1}}}
- X}
- X\fi
- X
- X% Debugging stuff.
- X%\let\markbothorig\markboth
- X%\def\markboth#1#2{\typeout{---Markboth: \#1=#1, \#2=#2\newline}
- X% \markbothorig {#1} {#2}}
- X%
- X%\let\markrightorig\markright
- X%\def\markright#1{\typeout{---Markright: \#1=#1\newline}
- X% \markrightorig {#1}}
- END_OF_FILE
- if test 4900 -ne `wc -c <'doc/nh.doc'`; then
- echo shar: \"'doc/nh.doc'\" unpacked with wrong size!
- fi
- # end of 'doc/nh.doc'
- fi
- if test -f 'info_file.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'info_file.c'\"
- else
- echo shar: Extracting \"'info_file.c'\" \(4399 characters\)
- sed "s/^X//" >'info_file.c' <<'END_OF_FILE'
- X/*
- X * $Id: info_file.c,v 5.1.1.1 90/01/11 17:07:25 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * Get info from file
- X */
- X
- X#include "am.h"
- X
- X#ifdef HAS_FILE_MAPS
- X#include <ctype.h>
- X#include <sys/stat.h>
- X
- X#define MAX_LINE_LEN 2048
- X
- Xstatic int read_line(buf, size, fp)
- Xchar *buf;
- Xint size;
- XFILE *fp;
- X{
- X int done = 0;
- X
- X do {
- X while (fgets(buf, size, fp)) {
- X int len = strlen(buf);
- X done += len;
- X if (len > 1 && buf[len-2] == '\\' &&
- X buf[len-1] == '\n') {
- X int ch;
- X buf += len - 2;
- X size -= len - 2;
- X /*
- X * Skip leading white space on next line
- X */
- X while ((ch = getc(fp)) != EOF &&
- X isascii(ch) && isspace(ch))
- X ;
- X (void) ungetc(ch, fp);
- X } else {
- X return done;
- X }
- X }
- X } while (size > 0 && !feof(fp));
- X
- X return done;
- X}
- X
- X/*
- X * Try to locate a key in a file
- X */
- Xstatic int search_or_reload_file(fp, map, key, val, m, fn)
- XFILE *fp;
- Xchar *map;
- Xchar *key;
- Xchar **val;
- Xmnt_map *m;
- Xvoid (*fn) P((mnt_map*, char*, char*));
- X{
- X char key_val[MAX_LINE_LEN];
- X int chuck = 0;
- X int line_no = 0;
- X
- X while (read_line(key_val, sizeof(key_val), fp)) {
- X char *kp;
- X char *cp;
- X char *hash;
- X int len = strlen(key_val);
- X line_no++;
- X
- X /*
- X * Make sure we got the whole line
- X */
- X if (key_val[len-1] != '\n') {
- X plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
- X chuck = 1;
- X } else {
- X key_val[len-1] = '\0';
- X }
- X
- X /*
- X * Strip comments
- X */
- X hash = strchr(key_val, '#');
- X if (hash)
- X *hash = '\0';
- X
- X /*
- X * Find start of key
- X */
- X for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
- X ;
- X
- X /*
- X * Ignore blank lines
- X */
- X if (!*kp)
- X goto again;
- X
- X /*
- X * Find end of key
- X */
- X for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
- X ;
- X
- X /*
- X * Check whether key matches
- X */
- X if (*cp)
- X *cp++ = '\0';
- X
- X if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
- X while (*cp && isascii(*cp) && isspace(*cp))
- X cp++;
- X if (*cp) {
- X /*
- X * Return a copy of the data
- X */
- X char *dc = strdup(cp);
- X if (fn)
- X (*fn)(m, kp, dc);
- X else
- X *val = dc;
- X#ifdef DEBUG
- X dlog("%s returns %s", key, dc);
- X#endif
- X if (!fn)
- X return 0;
- X } else {
- X plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
- X }
- X }
- X
- Xagain:
- X /*
- X * If the last read didn't get a whole line then
- X * throw away the remainder before continuing...
- X */
- X if (chuck) {
- X while (fgets(key_val, sizeof(key_val), fp) &&
- X !strchr(key_val, '\n'))
- X ;
- X chuck = 0;
- X }
- X }
- X
- X return fn ? 0 : ENOENT;
- X}
- X
- Xint file_init(map)
- Xchar *map;
- X{
- X FILE *mapf = fopen(map, "r");
- X if (mapf) {
- X (void) fclose(mapf);
- X return 0;
- X }
- X return errno;
- X}
- X
- Xint file_reload(m, map, fn)
- Xmnt_map *m;
- Xchar *map;
- Xvoid (*fn)();
- X{
- X FILE *mapf = fopen(map, "r");
- X if (mapf) {
- X int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
- X (void) fclose(mapf);
- X return error;
- X }
- X
- X return errno;
- X}
- X
- Xint file_search(m, map, key, pval, tp)
- Xmnt_map *m;
- Xchar *map;
- Xchar *key;
- Xchar **pval;
- Xtime_t *tp;
- X{
- X FILE *mapf = fopen(map, "r");
- X if (mapf) {
- X struct stat stb;
- X int error;
- X error = fstat(fileno(mapf), &stb);
- X if (!error && *tp < stb.st_mtime) {
- X *tp = stb.st_mtime;
- X error = -1;
- X } else {
- X error = search_or_reload_file(mapf, map, key, pval, 0, 0);
- X }
- X (void) fclose(mapf);
- X return error;
- X }
- X
- X return errno;
- X}
- X#endif
- END_OF_FILE
- if test 4399 -ne `wc -c <'info_file.c'`; then
- echo shar: \"'info_file.c'\" unpacked with wrong size!
- fi
- # end of 'info_file.c'
- fi
- if test -f 'mount_fs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mount_fs.c'\"
- else
- echo shar: Extracting \"'mount_fs.c'\" \(5414 characters\)
- sed "s/^X//" >'mount_fs.c' <<'END_OF_FILE'
- X/*
- X * $Id: mount_fs.c,v 5.1.1.2 90/01/11 17:10:47 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X#ifdef NFS_3
- Xtypedef nfs_fh fhandle_t;
- X#endif
- X#include <sys/mount.h>
- X
- X/*
- X * System Vr4 / SunOS 4.1 compatibility
- X * - put dev= in the options list
- X *
- X * From: Brent Callaghan <brent@eng.sun.com>
- X */
- X#define MNTINFO_DEV "dev"
- X#include <sys/stat.h>
- X
- Xint compute_mount_flags(mnt)
- Xstruct mntent *mnt;
- X{
- X int flags;
- X#ifdef NFS_4
- X flags = M_NEWTYPE;
- X#else
- X flags = 0;
- X#endif
- X
- X /*
- X * Crack basic mount options
- X */
- X flags |= hasmntopt(mnt, "ro") ? M_RDONLY : 0;
- X#ifdef M_CACHE
- X flags |= hasmntopt(mnt, "nocache") ? M_NOCACHE : 0;
- X#endif
- X#ifdef M_GRPID
- X flags |= hasmntopt(mnt, "grpid") ? M_GRPID : 0;
- X#endif
- X#ifdef M_MULTI
- X flags |= hasmntopt(mnt, "multi") ? M_MULTI : 0;
- X#endif
- X#ifdef M_NODEV
- X flags |= hasmntopt(mnt, "nodev") ? M_NODEV : 0;
- X#endif
- X#ifdef M_NOEXEC
- X flags |= hasmntopt(mnt, "noexec") ? M_NOEXEC : 0;
- X#endif
- X#ifdef M_NOSUB
- X flags |= hasmntopt(mnt, "nosub") ? M_NOSUB : 0;
- X#endif
- X#ifdef hpux
- X/* HP-UX has an annoying feature of printing error msgs on /dev/console */
- X#undef M_NOSUID
- X#endif
- X#ifdef M_NOSUID
- X flags |= hasmntopt(mnt, "nosuid") ? M_NOSUID : 0;
- X#endif
- X#ifdef M_SYNC
- X flags |= hasmntopt(mnt, "sync") ? M_SYNC : 0;
- X#endif
- X
- X return flags;
- X}
- X
- Xint mount_fs(mnt, flags, mnt_data, retry, type)
- Xstruct mntent *mnt;
- Xint flags;
- Xcaddr_t mnt_data;
- Xint retry;
- XMTYPE_TYPE type;
- X{
- X int error = 0;
- X int automount = 0;
- X#ifdef MNTINFO_DEV
- X struct stat stb;
- X char *xopts = 0;
- X#endif
- X
- X#ifdef DEBUG
- X#ifdef NFS_4
- X dlog("%s fstype %s (%s) flags %#x (%s)",
- X mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
- X#else
- X dlog("%s fstype %d (%s) flags %#x (%s)",
- X mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
- X#endif /* NFS_4 */
- X#endif /* DEBUG */
- X
- X /*
- X * Fake some mount table entries for the automounter
- X */
- X if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
- X automount = 1;
- X mnt->mnt_fsname = pid_fsname;
- X /*
- X * Try it with the normal name
- X */
- X#ifdef notdef
- X mnt->mnt_type = MNTTYPE_IGNORE;
- X#endif
- X mnt->mnt_type = MNTTYPE_NFS;
- X /*
- X * Background the mount, so that the stat of the
- X * mountpoint is done in a background process.
- X */
- X if (background())
- X return 0;
- X }
- X
- Xagain:
- X clock_valid = 0;
- X error = MOUNT_TRAP(type, mnt, flags, mnt_data);
- X if (error < 0)
- X plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir);
- X if (error < 0 && --retry > 0) {
- X sleep(1);
- X goto again;
- X }
- X if (error < 0) {
- X if (automount)
- X going_down(errno);
- X return errno;
- X }
- X
- X#ifdef UPDATE_MTAB
- X#ifdef MNTINFO_DEV
- X /*
- X * Add the extra dev= field to the mount table.
- X */
- X if (stat(mnt->mnt_dir, &stb) == 0) {
- X char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
- X xopts = mnt->mnt_opts;
- X if (sizeof(stb.st_dev) == 2) {
- X /* SunOS 4.1 */
- X sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV,
- X (u_long) stb.st_dev & 0xffff);
- X } else {
- X /* System Vr4 */
- X sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV,
- X (u_long) stb.st_dev);
- X }
- X mnt->mnt_opts = zopts;
- X }
- X#endif /* MNTINFO_DEV */
- X
- X#ifdef hpux
- X /*
- X * Yet another gratuitously incompatible change in HP-UX
- X */
- X mnt->mnt_time = clocktime();
- X#endif
- X write_mntent(mnt);
- X#ifdef MNTINFO_DEV
- X if (xopts) {
- X free(mnt->mnt_opts);
- X mnt->mnt_opts = xopts;
- X }
- X#endif
- X#endif /* UPDATE_MTAB */
- X
- X /*
- X * Needed this way since mnt may contain a pointer
- X * to a local variable in this stack frame.
- X */
- X if (automount)
- X going_down(0);
- X return 0;
- X}
- X
- X#ifdef NEED_MNTOPT_PARSER
- X/*
- X * Some systems don't provide these to the user,
- X * but amd needs them, so...
- X *
- X * From: Piete Brooks <pb@cl.cam.ac.uk>
- X */
- X
- X#include <ctype.h>
- X
- Xstatic char *nextmntopt(p)
- Xchar **p;
- X{
- X char *cp = *p;
- X char *rp;
- X /*
- X * Skip past white space
- X */
- X while (*cp && isspace(*cp))
- X cp++;
- X /*
- X * Word starts here
- X */
- X rp = cp;
- X /*
- X * Scan to send of string or separator
- X */
- X while (*cp && *cp != ',')
- X cp++;
- X /*
- X * If separator found the overwrite with nul char.
- X */
- X if (*cp) {
- X *cp = '\0';
- X cp++;
- X }
- X /*
- X * Return value for next call
- X */
- X *p = cp;
- X return rp;
- X}
- X
- Xchar *hasmntopt(mnt, opt)
- Xstruct mntent *mnt;
- Xchar *opt;
- X{
- X char t[MNTMAXSTR];
- X char *f;
- X char *o = t;
- X int l = strlen(opt);
- X strcpy(t, mnt->mnt_opts);
- X
- X while (*(f = nextmntopt(&o)))
- X if (strncmp(opt, f, l) == 0)
- X return f - t + mnt->mnt_opts;
- X
- X return 0;
- X}
- X#endif /* NEED_MNTOPT_PARSER */
- END_OF_FILE
- if test 5414 -ne `wc -c <'mount_fs.c'`; then
- echo shar: \"'mount_fs.c'\" unpacked with wrong size!
- fi
- # end of 'mount_fs.c'
- fi
- if test -f 'nfs_prot_svc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nfs_prot_svc.c'\"
- else
- echo shar: Extracting \"'nfs_prot_svc.c'\" \(4786 characters\)
- sed "s/^X//" >'nfs_prot_svc.c' <<'END_OF_FILE'
- X/*
- X * $Id: nfs_prot_svc.c,v 5.1 89/11/17 18:21:23 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1989 Jan-Simon Pendry
- X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1989 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X
- Xvoid nfs_program_2(rqstp, transp)
- Xstruct svc_req *rqstp;
- XSVCXPRT *transp;
- X{
- X union {
- X nfs_fh nfsproc_getattr_2_arg;
- X sattrargs nfsproc_setattr_2_arg;
- X diropargs nfsproc_lookup_2_arg;
- X nfs_fh nfsproc_readlink_2_arg;
- X readargs nfsproc_read_2_arg;
- X writeargs nfsproc_write_2_arg;
- X createargs nfsproc_create_2_arg;
- X diropargs nfsproc_remove_2_arg;
- X renameargs nfsproc_rename_2_arg;
- X linkargs nfsproc_link_2_arg;
- X symlinkargs nfsproc_symlink_2_arg;
- X createargs nfsproc_mkdir_2_arg;
- X diropargs nfsproc_rmdir_2_arg;
- X readdirargs nfsproc_readdir_2_arg;
- X nfs_fh nfsproc_statfs_2_arg;
- X } argument;
- X char *result;
- X bool_t (*xdr_argument)(), (*xdr_result)();
- X char *(*local)();
- X
- X switch (rqstp->rq_proc) {
- X case NFSPROC_NULL:
- X xdr_argument = xdr_void;
- X xdr_result = xdr_void;
- X local = (char *(*)()) nfsproc_null_2;
- X break;
- X
- X case NFSPROC_GETATTR:
- X xdr_argument = xdr_nfs_fh;
- X xdr_result = xdr_attrstat;
- X local = (char *(*)()) nfsproc_getattr_2;
- X break;
- X
- X case NFSPROC_SETATTR:
- X xdr_argument = xdr_sattrargs;
- X xdr_result = xdr_attrstat;
- X local = (char *(*)()) nfsproc_setattr_2;
- X break;
- X
- X case NFSPROC_ROOT:
- X xdr_argument = xdr_void;
- X xdr_result = xdr_void;
- X local = (char *(*)()) nfsproc_root_2;
- X break;
- X
- X case NFSPROC_LOOKUP:
- X xdr_argument = xdr_diropargs;
- X xdr_result = xdr_diropres;
- X local = (char *(*)()) nfsproc_lookup_2;
- X break;
- X
- X case NFSPROC_READLINK:
- X xdr_argument = xdr_nfs_fh;
- X xdr_result = xdr_readlinkres;
- X local = (char *(*)()) nfsproc_readlink_2;
- X break;
- X
- X case NFSPROC_READ:
- X xdr_argument = xdr_readargs;
- X xdr_result = xdr_readres;
- X local = (char *(*)()) nfsproc_read_2;
- X break;
- X
- X case NFSPROC_WRITECACHE:
- X xdr_argument = xdr_void;
- X xdr_result = xdr_void;
- X local = (char *(*)()) nfsproc_writecache_2;
- X break;
- X
- X case NFSPROC_WRITE:
- X xdr_argument = xdr_writeargs;
- X xdr_result = xdr_attrstat;
- X local = (char *(*)()) nfsproc_write_2;
- X break;
- X
- X case NFSPROC_CREATE:
- X xdr_argument = xdr_createargs;
- X xdr_result = xdr_diropres;
- X local = (char *(*)()) nfsproc_create_2;
- X break;
- X
- X case NFSPROC_REMOVE:
- X xdr_argument = xdr_diropargs;
- X xdr_result = xdr_nfsstat;
- X local = (char *(*)()) nfsproc_remove_2;
- X break;
- X
- X case NFSPROC_RENAME:
- X xdr_argument = xdr_renameargs;
- X xdr_result = xdr_nfsstat;
- X local = (char *(*)()) nfsproc_rename_2;
- X break;
- X
- X case NFSPROC_LINK:
- X xdr_argument = xdr_linkargs;
- X xdr_result = xdr_nfsstat;
- X local = (char *(*)()) nfsproc_link_2;
- X break;
- X
- X case NFSPROC_SYMLINK:
- X xdr_argument = xdr_symlinkargs;
- X xdr_result = xdr_nfsstat;
- X local = (char *(*)()) nfsproc_symlink_2;
- X break;
- X
- X case NFSPROC_MKDIR:
- X xdr_argument = xdr_createargs;
- X xdr_result = xdr_diropres;
- X local = (char *(*)()) nfsproc_mkdir_2;
- X break;
- X
- X case NFSPROC_RMDIR:
- X xdr_argument = xdr_diropargs;
- X xdr_result = xdr_nfsstat;
- X local = (char *(*)()) nfsproc_rmdir_2;
- X break;
- X
- X case NFSPROC_READDIR:
- X xdr_argument = xdr_readdirargs;
- X xdr_result = xdr_readdirres;
- X local = (char *(*)()) nfsproc_readdir_2;
- X break;
- X
- X case NFSPROC_STATFS:
- X xdr_argument = xdr_nfs_fh;
- X xdr_result = xdr_statfsres;
- X local = (char *(*)()) nfsproc_statfs_2;
- X break;
- X
- X default:
- X svcerr_noproc(transp);
- X return;
- X }
- X bzero((char *)&argument, sizeof(argument));
- X if (!svc_getargs(transp, xdr_argument, &argument)) {
- X svcerr_decode(transp);
- X return;
- X }
- X result = (*local)(&argument, rqstp);
- X if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
- X svcerr_systemerr(transp);
- X }
- X if (!svc_freeargs(transp, xdr_argument, &argument)) {
- X plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1");
- X going_down(1);
- X }
- X}
- X
- END_OF_FILE
- if test 4786 -ne `wc -c <'nfs_prot_svc.c'`; then
- echo shar: \"'nfs_prot_svc.c'\" unpacked with wrong size!
- fi
- # end of 'nfs_prot_svc.c'
- fi
- if test -f 'restart.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'restart.c'\"
- else
- echo shar: Extracting \"'restart.c'\" \(4527 characters\)
- sed "s/^X//" >'restart.c' <<'END_OF_FILE'
- X/*
- X * $Id: restart.c,v 5.1.1.2 90/01/11 17:18:41 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X
- X/*
- X * Handle an amd restart.
- X *
- X * Scan through the mount list finding all "interesting" mount points.
- X * Next hack up partial data structures and add the mounted file
- X * system to the list of known filesystems. This will leave a
- X * dangling reference to that filesystems, so when the filesystem is
- X * finally inherited, an extra "free" must be done on it.
- X *
- X * This module relies on internal details of other components. If
- X * you change something else make *sure* restart() still works.
- X */
- Xvoid restart()
- X{
- X /*
- X * Read the existing mount table
- X */
- X mntlist *ml, *mlp;
- X
- X /*
- X * For each entry, find nfs, ufs or auto mounts
- X * and create a partial am_node to represent it.
- X */
- X for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) {
- X struct mntent *me = mlp->mnt;
- X am_ops *fs_ops = 0;
- X if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) {
- X /*
- X * UFS entry
- X */
- X fs_ops = &ufs_ops;
- X } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) {
- X /*
- X * NFS entry, or possibly an Amd entry...
- X */
- X int au_pid;
- X char *colon = strchr(me->mnt_fsname, ':');
- X if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) {
- X plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
- X fs_ops = &sfs_ops;
- X } else {
- X fs_ops = &nfs_ops;
- X }
- X#ifdef MTAB_TYPE_MFS
- X } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) {
- X /*
- X * MFS entry. Fake with a symlink.
- X */
- X fs_ops = &sfs_ops;
- X#endif
- X } else {
- X /*
- X * Catch everything else with symlinks to
- X * avoid recursive mounts. This is debatable...
- X */
- X fs_ops = &sfs_ops;
- X }
- X
- X /*
- X * If we found something to do
- X */
- X if (fs_ops) {
- X mntfs *mf;
- X am_opts mo;
- X char *cp;
- X cp = strchr(me->mnt_fsname, ':');
- X /*
- X * Partially fake up an opts structure
- X */
- X mo.opt_rhost = 0;
- X mo.opt_rfs = 0;
- X if (cp) {
- X *cp = '\0';
- X mo.opt_rhost = strdup(me->mnt_fsname);
- X mo.opt_rfs = strdup(cp+1);
- X *cp = ':';
- X } else if (fs_ops->ffserver == find_nfs_srvr) {
- X /*
- X * Prototype 4.4 BSD used to end up here -
- X * might as well keep the workaround for now
- X */
- X plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
- X mo.opt_rhost = strdup(me->mnt_fsname);
- X mo.opt_rfs = strdup("/");
- X me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
- X }
- X mo.opt_fs = me->mnt_dir;
- X
- X /*
- X * Make a new mounted filesystem
- X */
- X mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
- X me->mnt_fsname, me->mnt_opts);
- X if (mf->mf_refc == 1) {
- X mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
- X mf->mf_error = 0; /* Already mounted correctly */
- X /*
- X * If the restarted type is a link then
- X * don't time out.
- X */
- X if (fs_ops == &sfs_ops)
- X mf->mf_flags |= MFF_RSTKEEP;
- X if (fs_ops->fs_init) {
- X /*
- X * Don't care whether this worked since
- X * it is checked again when the fs is
- X * inherited.
- X */
- X (void) (*fs_ops->fs_init)(mf);
- X }
- X
- X plog(XLOG_INFO, "%s restarted fstype %s on %s",
- X me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
- X } else {
- X /* Something strange happened - two mounts at the same place! */
- X free_mntfs(mf);
- X }
- X /*
- X * Clean up mo
- X */
- X if (mo.opt_rhost)
- X free(mo.opt_rhost);
- X if (mo.opt_rfs)
- X free(mo.opt_rfs);
- X }
- X }
- X
- X /*
- X * Free the mount list
- X */
- X free_mntlist(ml);
- X}
- END_OF_FILE
- if test 4527 -ne `wc -c <'restart.c'`; then
- echo shar: \"'restart.c'\" unpacked with wrong size!
- fi
- # end of 'restart.c'
- fi
- if test -f 'sched.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sched.c'\"
- else
- echo shar: Extracting \"'sched.c'\" \(4945 characters\)
- sed "s/^X//" >'sched.c' <<'END_OF_FILE'
- X/*
- X * $Id: sched.c,v 5.1.1.1 90/01/11 17:19:12 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * Process scheduler
- X */
- X
- X#include "am.h"
- X#include <sys/signal.h>
- X#include WAIT
- X#include <setjmp.h>
- Xextern jmp_buf select_intr;
- Xextern int select_intr_valid;
- X
- Xtypedef struct pjob pjob;
- Xstruct pjob {
- X qelem hdr; /* Linked list */
- X int pid; /* Process ID of job */
- X cb_fun cb_fun; /* Callback function */
- X voidp cb_closure; /* Closure for callback */
- X union wait w; /* Status filled in by sigchld */
- X voidp wchan; /* Wait channel */
- X};
- X
- Xextern qelem proc_list_head;
- Xqelem proc_list_head = { &proc_list_head, &proc_list_head };
- Xextern qelem proc_wait_list;
- Xqelem proc_wait_list = { &proc_wait_list, &proc_wait_list };
- X
- Xint task_notify_todo;
- X
- Xvoid ins_que(elem, pred)
- Xqelem *elem, *pred;
- X{
- X qelem *p = pred->q_forw;
- X elem->q_back = pred;
- X elem->q_forw = p;
- X pred->q_forw = elem;
- X p->q_back = elem;
- X}
- X
- Xvoid rem_que(elem)
- Xqelem *elem;
- X{
- X qelem *p = elem->q_forw;
- X qelem *p2 = elem->q_back;
- X p2->q_forw = p;
- X p->q_back = p2;
- X}
- X
- Xstatic pjob *sched_job(cf, ca)
- Xcb_fun cf;
- Xvoidp ca;
- X{
- X pjob *p = ALLOC(pjob);
- X
- X p->cb_fun = cf;
- X p->cb_closure = ca;
- X
- X /*
- X * Now place on wait queue
- X */
- X ins_que(&p->hdr, &proc_wait_list);
- X
- X return p;
- X}
- X
- Xvoid run_task(tf, ta, cf, ca)
- Xtask_fun tf;
- Xvoidp ta;
- Xcb_fun cf;
- Xvoidp ca;
- X{
- X pjob *p = sched_job(cf, ca);
- X int mask;
- X
- X p->wchan = (voidp) p;
- X
- X mask = sigblock(sigmask(SIGCHLD));
- X
- X if (p->pid = background()) {
- X sigsetmask(mask);
- X return;
- X }
- X
- X exit((*tf)(ta));
- X /* firewall... */
- X abort();
- X}
- X
- X/*
- X * Schedule a task to be run when woken up
- X */
- Xvoid sched_task(cf, ca, wchan)
- Xcb_fun cf;
- Xvoidp ca;
- Xvoidp wchan;
- X{
- X /*
- X * Allocate a new task
- X */
- X pjob *p = sched_job(cf, ca);
- X#ifdef DEBUG
- X /*dlog("sleep(%#x)", wchan);*/
- X#endif
- X p->wchan = wchan;
- X p->pid = 0;
- X bzero((voidp) &p->w, sizeof(p->w));
- X}
- X
- Xstatic void wakeupjob(p)
- Xpjob *p;
- X{
- X rem_que(&p->hdr);
- X ins_que(&p->hdr, &proc_list_head);
- X task_notify_todo++;
- X}
- X
- Xvoid wakeup(wchan)
- Xvoidp wchan;
- X{
- X pjob *p, *p2;
- X
- X if (!foreground)
- X return;
- X
- X#ifdef DEBUG
- X /*dlog("wakeup(%#x)", wchan);*/
- X#endif
- X /*
- X * Can't user ITER() here because
- X * wakeupjob() juggles the list.
- X */
- X for (p = FIRST(pjob, &proc_wait_list);
- X p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
- X p = p2) {
- X if (p->wchan == wchan)
- X wakeupjob(p);
- X }
- X}
- X
- Xvoid wakeup_task(rc, term, cl)
- Xint rc;
- Xint term;
- Xvoidp cl;
- X{
- X wakeup(cl);
- X}
- X
- X/*ARGSUSED*/
- Xvoid sigchld(sig)
- Xint sig;
- X{
- X union wait w;
- X int pid;
- X
- X#ifdef SYS5_SIGNALS
- X if ((pid = wait(&w)) > 0) {
- X#else
- X while ((pid = wait3(&w, WNOHANG, (union wait *) 0)) > 0) {
- X#endif
- X pjob *p, *p2;
- X
- X if (WIFSIGNALED(w))
- X plog(XLOG_ERROR, "Process %d exited with signal %d",
- X pid, w.w_termsig);
- X#ifdef DEBUG
- X else
- X dlog("Process %d exited with status %d",
- X pid, w.w_retcode);
- X#endif
- X
- X for (p = FIRST(pjob, &proc_wait_list);
- X p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
- X p = p2) {
- X if (p->pid == pid) {
- X p->w = w;
- X wakeupjob(p);
- X break;
- X }
- X }
- X
- X#ifdef DEBUG
- X if (p) ; else dlog("can't locate task block for pid %d", pid);
- X#endif
- X }
- X
- X#ifdef SYS5_SIGNALS
- X signal(sig, sigchld);
- X#endif
- X if (select_intr_valid)
- X longjmp(select_intr, sigchld);
- X}
- X
- X/*
- X * Run any pending tasks.
- X * This must be called with SIGCHLD disabled
- X */
- Xvoid task_notify(P_void)
- X{
- X /*
- X * Keep taking the first item off the list and processing it.
- X *
- X * Done this way because the the callback can, quite reasonably,
- X * queue a new task, so no local reference into the list can be
- X * held here.
- X */
- X while (FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {
- X pjob *p = FIRST(pjob, &proc_list_head);
- X rem_que(&p->hdr);
- X /*
- X * This job has completed
- X */
- X --task_notify_todo;
- X
- X /*
- X * Do callback if it exists
- X */
- X if (p->cb_fun)
- X (*p->cb_fun)(p->w.w_retcode,
- X p->w.w_termsig, p->cb_closure);
- X
- X free(p);
- X }
- X}
- END_OF_FILE
- if test 4945 -ne `wc -c <'sched.c'`; then
- echo shar: \"'sched.c'\" unpacked with wrong size!
- fi
- # end of 'sched.c'
- fi
- echo shar: End of archive 4 \(of 13\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 13 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
-